/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Util.Utilitarioxml;

import Entidades.Address;
import Entidades.Client;
import Entidades.Hardware;
import Entidades.Item;
import Entidades.Orderes;
import Entidades.Product;
import Entidades.Software;
import Entidades.Supply;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.IIOException;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
import util.utilitarioJavaMail.InboxReader;
/**
 * @author Pedro
 *
 * Esse Controlador irá controlar a leitura de um arquivo xml, e traduzir
 * gerando os devidos objetos e salvando no BD
 *
 *
 */
public class XMLunmarshalling {

   
    private String pathFileXml;
    private File fileXml;
    private SAXBuilder processadorXml = new SAXBuilder();
    private Document document;

    /**
     *
     * @param file endereço do arquivo no sistema de arquivo
     * @throws IOException caso o arquivo existe ou se esta com a sitaxe
     * incorreta
     */
    public XMLunmarshalling(File file) throws IOException, Exception {

        this.pathFileXml = file.getName();
        fileXml = file;

        if (!fileXml.exists()) {
            throw new IIOException("Arquivo não Encontrado");
        }

        try {
            this.processadorXml = new SAXBuilder(XMLReaders.DTDVALIDATING);
            System.out.println( this.processadorXml.isValidating());
            this.processadorXml.isValidating();
            if(this.processadorXml.isValidating() == false)
            {
                throw  new Exception("Arquivo não padronizado");
            }
            this.document = this.processadorXml.build(fileXml);
        } catch (JDOMException ex) {
            throw new IOException("Erro na leitura do arquivo: " + ex.getMessage());
        }
    }

    /**
     *
     * @return retorna o enderço do arquivo xml
     */
    public String getPathFileXml() {
        return pathFileXml;
    }

    /**
     *
     * @return a ordem de pedido que estava no arquivo xml
     */
    public Orderes getPedido() {

        Orderes pedido;
        Element root, customer, itens;
        ArrayList<Item> lstItens;

        String numeroPedido;
        Client customerObj;

        pedido = new Orderes();
        root = document.getRootElement();
        numeroPedido = root.getAttributeValue("number");
        System.out.println(numeroPedido);
        pedido.setNumber(Integer.parseInt(numeroPedido));

        customer = root.getChild("cliente");
        customerObj = this.elementeForCliente(customer);
        pedido.setClient(customerObj);

        lstItens = new ArrayList<>();
        itens = root.getChild("itemdeLinha");
        for (Element elemento : itens.getChildren()) {
            Item item = this.elementForItem(elemento);
            lstItens.add(item);
        }
        pedido.setItem(lstItens);
        return pedido;
    }

    /**
     * Transforma o elemento que representa um cliente em um objeto cliente
     */
    private Client elementeForCliente(Element element) {
        Element addressCustomer;
        Address addressCustomerObj;
        String idCustomer, nomeCustomer;
        Client cliente;


        addressCustomer = element.getChild("endereco");
        addressCustomerObj = this.elementForAddress(addressCustomer);
        idCustomer = element.getAttributeValue("custumerID");
        nomeCustomer = element.getAttributeValue("name");

        cliente = new Client();
        cliente.setId(Integer.parseInt(idCustomer));
        cliente.setName(nomeCustomer);
        cliente.setAddress(addressCustomerObj);
        return cliente;
    }

    /**
     * Transforma o elemento que representa um item em um objeto Item
     */
    private Item elementForItem(Element element) {
        Item item;
        Product produto;
        Element elementeTiproduto;
        String quantidade;

        quantidade = element.getAttributeValue("quantity");
        elementeTiproduto = element.getChild("type");
        //System.out.println(elementeTiproduto.toString());
        produto = this.elementForProduct(elementeTiproduto);

        item = new Item();
        item.setProduct(produto);
        item.setQuanttity(Integer.parseInt(quantidade));

        return item;
    }

    /**
     * *
     * Transforma o elemento que representa um produto em um objeto produto
     *
     */
    private Product elementForProduct(Element element) {
        Element fornecedor;
        Product product = null;
        Supply fornecedorObj = null;
        String tipo, descricao, percoUnitario, versao, assemby;

        tipo = element.getAttributeValue("type");
        descricao = element.getAttributeValue("description");
        percoUnitario = element.getAttributeValue("unitPrice");
        assemby = element.getAttributeValue("assembly");
        versao = element.getAttributeValue("version");
        
        fornecedor = element.getChild("fornecedor");

        fornecedorObj = this.elementeForSupply(fornecedor);

        if (tipo.equalsIgnoreCase("software")) {
            product = new Software();
            ((Software) product).setVersion(versao);
        } else if (tipo.equalsIgnoreCase("hardware")) {
            product = new Hardware();
            ((Hardware) product).setAssembly(assemby);
        }

        product.setDescription(descricao);
        product.setPrice(Double.parseDouble(percoUnitario));
        product.setSupply(fornecedorObj);

        return product;
    }

    /**
     * *
     * Transforma o elemento que representa um endereço em um objeto Address
     *
     */
    private Address elementForAddress(Element elemento) {
        Address address;

        String street, city, state, postalcode, country;

        street = elemento.getAttributeValue("street");
        city = elemento.getAttributeValue("city");
        state = elemento.getAttributeValue("stateProvince");
        postalcode = elemento.getAttributeValue("postalCode");
        country = elemento.getAttributeValue("country");

        address = new Address();
        address.setStreet(street);
        address.setCity(city);
        address.setStateORprovince(state);
        address.setPostalCode(postalcode);
        address.setContry(country);

        return address;
    }

    private Supply elementeForSupply(Element fornecedor) {
        Supply retorno = null;
        Element address;
        Address addresObj;
        String id, nome;

        id = fornecedor.getAttributeValue("number");
        nome = fornecedor.getAttributeValue("name");
        address = fornecedor.getChild("endereco");
        addresObj = this.elementForAddress(address);

        retorno = new Supply();
        retorno.setID(Integer.parseInt(id));
        retorno.setName(nome);
        retorno.setAddress(addresObj);

        return retorno;
    }
}
